﻿//========================================================= 
/**@file async.h
 * @brief 用于异步并发操作的一些类
 * 
 * @date 2017-06-14   12:02:39
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_ASYNC_H_
#define _LIBZHOUYB_ASYNC_H_
//--------------------------------------------------------- 
#include "../base/Define.h"
//--------------------------------------------------------- 
#ifdef _MSC_VER
#include <Windows.h>
#else
#include <pthread.h>
#include <errno.h>
#endif
//--------------------------------------------------------- 
namespace zhou_yb {
namespace container {
//--------------------------------------------------------- 
/**
 * @brief 互斥锁
 * @date 2017-06-14 12:40
 */
template<class T>
struct async_lock
{
    DisableObjConsturctCopyBehavior(async_lock)
protected:
    T* _obj;
public:
    async_lock(T& obj)
    {
        _obj = &obj;
        _obj->lock();
    }
    virtual ~async_lock()
    {
        _obj->unlock();
    }
};
//--------------------------------------------------------- 
#ifdef _MSC_VER
/**
 * @brief Windows下互斥对象
 * @date 2017-06-14 12:03
 */
class async_mutex
{
    DisableObjConsturctCopyBehavior(async_mutex)
protected:
    HANDLE _hMutex;
public:
    async_mutex()
    {
        _hMutex = CreateMutex(NULL, FALSE, NULL);
    }
    async_mutex(HANDLE hMutex) : _hMutex(hMutex) {}
    virtual ~async_mutex()
    {
        if(isValid())
        {
            CloseHandle(_hMutex);
            _hMutex = INVALID_HANDLE_VALUE;
        }
    }
    inline bool isValid() const
    {
        return _hMutex != INVALID_HANDLE_VALUE;
    }
    bool lock_timeout(uint timeoutMs)
    {
        if(!isValid())
            return false;
        DWORD dwRet = WaitForSingleObject(_hMutex, static_cast<DWORD>(timeoutMs));
        return (dwRet == WAIT_OBJECT_0) || (dwRet == WAIT_ABANDONED);
    }
    inline bool try_lock()
    {
        return lock_timeout(0);
    }
    inline bool lock()
    {
        return lock_timeout(INFINITE);
    }
    bool unlock()
    {
        if(!isValid())
            return false;
        return Tobool(ReleaseMutex(_hMutex));
    }
};
#else
/**
 * @brief Linux下互斥对象
 * @date 2017-06-14 12:03
 */
class async_mutex
{
    DisableObjConsturctCopyBehavior(async_mutex)
protected:
    pthread_mutex_t _mutex;
public:
    async_mutex()
    {
        #ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
            pthread_mutex_t m = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
        #else
            pthread_mutex_t m = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
        #endif
        _mutex = m;
    }
    virtual ~async_mutex()
    {
        pthread_mutex_destroy(&_mutex);
    }
    bool try_lock()
    {
        int v = pthread_mutex_trylock(&_mutex);
        return (v == 0) || (v == EDEADLK);
    }
    bool lock()
    {
        int v = pthread_mutex_lock(&_mutex);
        return (v == 0) || (v == EDEADLK);
    }
    bool unlock()
    {
        return 0 == pthread_mutex_unlock(&_mutex);
    }
};
#endif
//--------------------------------------------------------- 
} // napespace container
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_ASYNC_H_
//========================================================= 